package org.springblade.modules.admin.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.util.NumberUtil;
import cn.hutool.core.util.ObjectUtil;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import org.apache.ibatis.annotations.Param;
import org.springblade.core.log.exception.ServiceException;
import org.springblade.core.mp.base.BaseEntity;
import org.springblade.core.mp.base.BaseServiceImpl;
import org.springblade.core.secure.utils.AuthUtil;
import org.springblade.core.tool.constant.BladeConstant;
import org.springblade.modules.admin.dto.TaskPlanPageQueryDTO;
import org.springblade.modules.admin.dto.TaskPlanSaveDTO;
import org.springblade.modules.admin.entity.MaintainTaskPlanTemplate;
import org.springblade.modules.admin.enums.PeriodTypeEnum;
import org.springblade.modules.admin.service.MaintainTaskPlanTemplateService;
import org.springblade.modules.admin.vo.TaskPlanVO;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.*;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.stream.Collectors;

import org.springblade.modules.admin.mapper.MaintainTaskPlanMapper;
import org.springblade.modules.admin.entity.MaintainTaskPlan;
import org.springblade.modules.admin.service.MaintainTaskPlanService;
import org.springframework.transaction.annotation.Transactional;

/**
 * @Date 14:03 2022/3/14
 * @Description {
 *   任务计划业务层
 * }
 * @Author lsay
 **/
@Service
public class MaintainTaskPlanServiceImpl extends BaseServiceImpl<MaintainTaskPlanMapper, MaintainTaskPlan> implements MaintainTaskPlanService{

	@Autowired
	private MaintainTaskPlanTemplateService taskPlanTemplateService;

	@Override
	public IPage<TaskPlanVO> selectTaskPlanPage(TaskPlanPageQueryDTO pageQuery, IPage<TaskPlanVO> page) {
		List<String> tenantIds = new ArrayList<>();
		tenantIds.add(AuthUtil.getTenantId());
		tenantIds.add(BladeConstant.ADMIN_TENANT_ID);
		return page.setRecords(baseMapper.selectTaskPlanPage(pageQuery,tenantIds,page));
	}

	@Override
	public TaskPlanVO selectTaskPlanDetail(Long id) {
		return baseMapper.selectTaskPlanDetail(id);
	}

	@Override
	public List<TaskPlanVO> getTaskPlanSelectDown() {
		List<String> tenantIds = new ArrayList<>();
		tenantIds.add(AuthUtil.getTenantId());
		tenantIds.add(BladeConstant.ADMIN_TENANT_ID);
		return baseMapper.getTaskPlanSelectDown(tenantIds);
	}

	@Override
	@Transactional(rollbackFor = Exception.class)
	public Boolean saveTaskPlan(TaskPlanSaveDTO taskPlanSaveDTO) {

		checkPeriod(taskPlanSaveDTO.getTaskPlanTemplates());

		MaintainTaskPlan taskPlan = new MaintainTaskPlan();
		BeanUtil.copyProperties(taskPlanSaveDTO,taskPlan);
		this.save(taskPlan);

		if(ObjectUtil.isNotEmpty(taskPlanSaveDTO.getTaskPlanTemplates())){
			taskPlanSaveDTO.getTaskPlanTemplates().forEach(e -> {
				e.setTaskPlanId(taskPlan.getId());
			});
			taskPlanTemplateService.saveBatch(taskPlanSaveDTO.getTaskPlanTemplates());
		}
		return Boolean.TRUE;
	}

	@Override
	@Transactional(rollbackFor = Exception.class)
	public Boolean updateTaskPlan(Long id, TaskPlanSaveDTO taskPlanSaveDTO) {

		checkPeriod(taskPlanSaveDTO.getTaskPlanTemplates());

		MaintainTaskPlan taskPlan = new MaintainTaskPlan();
		BeanUtil.copyProperties(taskPlanSaveDTO,taskPlan);
		taskPlan.setId(id);
		this.updateById(taskPlan);

		if(ObjectUtil.isNotEmpty(taskPlanSaveDTO.getTaskPlanTemplates())){
			// 批量更新现有数据或新增
			taskPlanTemplateService.saveOrUpdateBatch(taskPlanSaveDTO.getTaskPlanTemplates());
			// 根据现有id 删除可能取消的关联
			List<Long> ids = taskPlanSaveDTO.getTaskPlanTemplates().stream().map(BaseEntity::getId).collect(Collectors.toList());
			taskPlanTemplateService.remove(Wrappers.<MaintainTaskPlanTemplate>lambdaQuery().eq(MaintainTaskPlanTemplate::getTaskPlanId,id).notIn(MaintainTaskPlanTemplate::getId,ids));
		}

		return Boolean.TRUE;
	}

	@Override
	@Transactional(rollbackFor = Exception.class)
	public Boolean copyTaskPlan(Long id) {

		MaintainTaskPlan oldTaskPlan = this.getById(id);
		MaintainTaskPlan newTaskPlan = new MaintainTaskPlan();
		BeanUtil.copyProperties(oldTaskPlan,newTaskPlan, "id","tenantId","createTime","createUser","updateTime","updateUser","createDept","status","isDeleted");
		String newName = oldTaskPlan.getName()+"—复制"+ String.format("%04d",new Random().nextInt(9999));
		newTaskPlan.setName(newName);
		newTaskPlan.setTenantId(AuthUtil.getTenantId());
		this.save(newTaskPlan);

		List<MaintainTaskPlanTemplate> oldTaskPlanTemplates = taskPlanTemplateService.list(Wrappers.<MaintainTaskPlanTemplate>lambdaQuery().eq(MaintainTaskPlanTemplate::getTaskPlanId,id));
		List<MaintainTaskPlanTemplate> newTaskPlanTemplates = new ArrayList<>();
		oldTaskPlanTemplates.forEach(e -> {
			MaintainTaskPlanTemplate taskPlanTemplate = new MaintainTaskPlanTemplate();
			BeanUtil.copyProperties(e,taskPlanTemplate,"id","tenantId","createTime","createUser","updateTime","updateUser","createDept","status","isDeleted");
			taskPlanTemplate.setTaskPlanId(newTaskPlan.getId());
			taskPlanTemplate.setTenantId(AuthUtil.getTenantId());
			newTaskPlanTemplates.add(taskPlanTemplate);
		});
		taskPlanTemplateService.saveBatch(newTaskPlanTemplates);
		return Boolean.TRUE;
	}

	/**
	 * 检查关联模板周期
	 * @param taskPlanTemplates
	 * @return
	 */
	private void checkPeriod(List<MaintainTaskPlanTemplate> taskPlanTemplates){

		if(ObjectUtil.isEmpty(taskPlanTemplates)){
			return;
		}

		List<MaintainTaskPlanTemplate> periods = taskPlanTemplates.stream().filter(e -> PeriodTypeEnum.PERIOD.getId() == e.getPeriodType()).collect(Collectors.toList());
		List<MaintainTaskPlanTemplate> fixedMonths = taskPlanTemplates.stream().filter(e -> PeriodTypeEnum.FIXED_MONTH.getId() == e.getPeriodType()).collect(Collectors.toList());
		if(ObjectUtil.isNotEmpty(periods) && periods.size() > 1){
			int index = 0;
			Set<String> set = new HashSet<>();
			for (int i = 0; i < periods.size(); i++) {
				index++;
				set.add(periods.get(i).getPeriod());
			}
			if(set.size() < index){
				throw new ServiceException("相同周期类型下，周期值不可重复！");
			}
		}
		if(ObjectUtil.isNotEmpty(fixedMonths) && fixedMonths.size() > 1){
			int index = 0;
			Set<String> set = new HashSet<>();
			for (int i = 0; i < fixedMonths.size(); i++) {
				String[] arr = fixedMonths.get(i).getPeriod().split(",");
				for (String str: arr) {
					index++;
					set.add(str);
				}
			}
			if(set.size() < index){
				throw new ServiceException("相同周期类型下，周期值不可重复！");
			}
		}

	}

	@Override
	public List<MaintainTaskPlan> getTaskPlanByElevatorIds(List<Long> elevatorIds,String tenantId) {
		return baseMapper.getTaskPlanByElevatorIds(elevatorIds,tenantId);
	}

	@Override
	public MaintainTaskPlan getByIdAndTenantId(Long id,String tenantId) {

		return baseMapper.getByIdAndTenantId(id,tenantId);
	}
}
